﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonEngine.Resource
{
    /// <summary>
    /// 数据权限的许可数据源
    /// </summary>
    public abstract class PermissionedData
    {
        public const string PermissionedToAllValue = "all";
        public const string SplitString = "|";

        bool permissionedToall;

        public bool PermissionedToAll
        {
            get { return this.permissionedToall; }
            set { this.permissionedToall = value; }
        }

        public abstract bool PermissionedToNone { get; }
    }

    /// <summary>
    /// 权限允许的范围条件（数据加工类封装）
    /// </summary>
    public class PermissionedScopeData<TData> : PermissionedData
    {
        public ScopeData<TData> ScopeData { get; private set; }

        public PermissionedScopeData()
        {
            ScopeData = new ScopeData<TData>();
        }

        public override bool PermissionedToNone
        {
            get { return !PermissionedToAll && ScopeData.IsEmpty; }
        }

        public override string ToString()
        {
            if (PermissionedToAll)
                return PermissionedData.PermissionedToAllValue;

            return ScopeData.ToString();
        }

        public static PermissionedScopeData<TData> BuildFromString(string data)
        {
            PermissionedScopeData<TData> result = new PermissionedScopeData<TData>();

            if (data != null)
            {
                if (data == PermissionedData.PermissionedToAllValue)
                {
                    result.PermissionedToAll = true;
                }
                else
                {
                    result.ScopeData = ScopeData<TData>.BuildFromString(data);
                }
            }
            return result;
        }
    }
    /// <summary>
    /// 权限允许的范围条件集（数据加工类封装）
    /// </summary>
    public class PermissionedScopeDataList<TData> : PermissionedData
    {
        public List<ScopeData<TData>> ScopeDataList { get; private set; }

        public PermissionedScopeDataList()
        {
            ScopeDataList = new List<ScopeData<TData>>();
        }

        public override bool PermissionedToNone
        {
            get { return !PermissionedToAll && (ScopeDataList.Count == 0 || ScopeDataList.All(s => s.IsEmpty)); }
        }
    }

    /// <summary>
    /// 权限允许的集合条件（数据加工类封装）
    /// </summary>
    public class PermissionedCollectionData<TItem> : PermissionedData
    {
        List<TItem> permissionedItems;

        public List<TItem> PermissionedItems { get { return this.permissionedItems; } }

        public PermissionedCollectionData()
        {
            permissionedItems = new List<TItem>();
        }

        public override bool PermissionedToNone
        {
            get { return !PermissionedToAll && permissionedItems.Count == 0; }
        }

        public override string ToString()
        {
            if (PermissionedToAll)
                return PermissionedData.PermissionedToAllValue;

            if (PermissionedItems.Count == 0)
                return string.Empty;

            StringBuilder sb = new StringBuilder();

            foreach (var item in permissionedItems)
            {
                string value = Condition.ConvertValueToString(item);
                sb.Append(value);
                sb.Append(PermissionedData.SplitString);
            }
            sb.Remove(sb.Length - PermissionedData.SplitString.Length, PermissionedData.SplitString.Length);
            return sb.ToString();
        }

        public static PermissionedCollectionData<TItem> BuildFromString(string value)
        {
            PermissionedCollectionData<TItem> result = new PermissionedCollectionData<TItem>();

            if (value != null)
            {
                if (value == PermissionedData.PermissionedToAllValue)
                {
                    result.PermissionedToAll = true;
                }
                else
                {
                    string[] items = value.Split(new string[] { PermissionedData.SplitString }, StringSplitOptions.RemoveEmptyEntries);

                    foreach (var item in items)
                    {
                        var o = Condition.GetValueFromString<TItem>(item);
                        result.permissionedItems.Add(o);
                    }
                }
            }

            return result;
        }

        public static PermissionedCollectionData<TItem> BuildFromStringList(IList<string> list)
        {
            PermissionedCollectionData<TItem> result = new PermissionedCollectionData<TItem>();

            if (list == null || list.Count == 0)
                return result;

            if (list.Any(d => d == PermissionedData.PermissionedToAllValue))
            {
                result.PermissionedToAll = true;
                return result;
            }

            var items = list.SelectMany(d => d.Split(new string[] { PermissionedData.SplitString }, StringSplitOptions.RemoveEmptyEntries)).Distinct();

            foreach (var item in items)
            {
                var o = Condition.GetValueFromString<TItem>(item);
                result.permissionedItems.Add(o);
            }
            return result;
        }
    }

    /// <summary>
    /// 数据范围的字符串处理加工
    /// </summary>
    public class ScopeData<TData>
    {
        public const string GreaterLess = "< scope <";
        public const string GreaterLessEqual = " < scope <= ";
        public const string GreaterEqualLess = " <= scope < ";
        public const string GreaterEqualLessEqual = " <= scope <= ";

        public TData Min { get; set; }
        public TData Max { get; set; }

        public bool HasMin { get; set; }
        public bool HasMax { get; set; }

        public bool IsEmpty { get { return !HasMin && !HasMax; } }

        public ScopeType ScopeType { get; set; }

        public override string ToString()
        {
            string min = string.Empty;
            string max = string.Empty;
            string split = string.Empty;

            if (HasMin)
                min = Condition.ConvertValueToString(Min);

            if (HasMax)
                max = Condition.ConvertValueToString(Max);

            switch (ScopeType)
            {
                case ScopeType.GreaterLess:
                    split = GreaterLess;
                    break;
                case ScopeType.GreaterLessEqual:
                    split = GreaterLessEqual;
                    break;
                case ScopeType.GreaterEqualLess:
                    split = GreaterEqualLess;
                    break;
                case ScopeType.GreaterEqualLessEqual:
                    split = GreaterEqualLessEqual;
                    break;
                default:
                    break;
            }
            if (IsEmpty)
                split = string.Empty;

            return min + split + max;
        }

        public static ScopeData<TData> BuildFromString(string data)
        {
            ScopeData<TData> result = new ScopeData<TData>();

            if (data == null)
                data = string.Empty;

            string[] items = null;

            if (data.Contains(GreaterLess))
            {
                items = data.Split(new string[] { GreaterLess }, StringSplitOptions.None);
                result.ScopeType = ScopeType.GreaterLess;
            }
            else if (data.Contains(GreaterLessEqual))
            {
                items = data.Split(new string[] { GreaterLessEqual }, StringSplitOptions.None);
                result.ScopeType = ScopeType.GreaterLessEqual;
            }
            else if (data.Contains(GreaterEqualLess))
            {
                items = data.Split(new string[] { GreaterEqualLess }, StringSplitOptions.None);
                result.ScopeType = ScopeType.GreaterEqualLess;
            }
            else if (data.Contains(GreaterEqualLessEqual))
            {
                items = data.Split(new string[] { GreaterEqualLessEqual }, StringSplitOptions.None);
                result.ScopeType = ScopeType.GreaterEqualLessEqual;
            }

            if (items != null)
            {
                if (items[0] != string.Empty)
                {
                    result.Min = Condition.GetValueFromString<TData>(items[0]);
                    result.HasMin = true;
                }

                if (items[1] != string.Empty)
                {
                    result.Max = Condition.GetValueFromString<TData>(items[1]);
                    result.HasMax = true;
                }
            }
            return result;
        }
    }
    /// <summary>
    /// 范围比对类型
    /// </summary>
    public enum ScopeType
    {
        GreaterLess,
        GreaterLessEqual,
        GreaterEqualLess,
        GreaterEqualLessEqual
    }
}
